//
// Created by Administrator on 25-7-11.
//

#include "main_global.h"



volatile uint8_t old_pos = 0;

void HAL_UART_IDLECallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1)
    {
        // 停止 DMA 接收
        __HAL_DMA_DISABLE(huart->hdmarx);

        // 当前写入位置
        uint8_t  new_pos = USART_DMA_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx);

        // 拷贝收到的数据
        if (new_pos != old_pos)
        {
            uint8_t  data_len = (new_pos > old_pos) ? (new_pos - old_pos) : (USART_DMA_BUFFER_SIZE - old_pos + new_pos);

            for (uint16_t i = 0; i < data_len; ++i)
            {
                rx_proc_buffer[i] = rx_dma_buffer[(old_pos + i) % USART_DMA_BUFFER_SIZE];
            }

            // 将处理缓冲区发送给帧解析器
            parse_uart_frame(rx_proc_buffer, data_len);

            old_pos = new_pos;
        }

        // 重新启动 DMA
        __HAL_DMA_SET_COUNTER(huart->hdmarx, USART_DMA_BUFFER_SIZE);
        __HAL_DMA_ENABLE(huart->hdmarx);
    }
}

void parse_uart_frame(uint8_t *data, uint16_t len)
{
    static FrameState state = FRAME_WAIT_HEAD;
    static uint8_t frame_buffer[12];
    static uint8_t frame_index = 0;

    for (uint16_t i = 0; i < len; i++)
    {
        uint8_t byte = data[i];

        switch (state)
        {
            case FRAME_WAIT_HEAD:
                if (byte == 0xA0) {
                    frame_index = 0;
                    frame_buffer[frame_index++] = byte;
                    state = FRAME_RECEIVING;
                }
                break;

            case FRAME_RECEIVING:
                frame_buffer[frame_index++] = byte;

                if (frame_index == 10)
                {
                    if (frame_buffer[9] == 0xA1)  // 帧尾校验
                    {
                        UsartRaw_t frame;
                        memcpy(frame.data, &frame_buffer[1], 8);
                        osMessageQueuePut(UsartQueueHandle, &frame, 0, 0);
                        osSemaphoreRelease(UsartReadySemHandle);
                    }
                    // 无论成功失败，恢复初始状态
                    state = FRAME_WAIT_HEAD;
                }
                break;
        }
    }
}


void emergency_handle(const char *reason) {
    // 1. 构造错误信息
    uint8_t buf[128];
    int len = snprintf((char*)buf, sizeof(buf),
                      "[EMERGENCY] %s\r\nSystem will reboot...\r\n", reason);

    // 2. 阻塞式发送错误信息（确保发送完成）
    HAL_UART_Transmit(&huart1, buf, len, HAL_MAX_DELAY);

    // 3. 硬件安全处理
    set_motor_throttle(0, 0);      // 电机急停
    servo_pwm_set(1450);           // 舵机回中

    // 4. 延时确保消息发送完成
    HAL_Delay(50);  // 115200bps下128字节约需11ms

    // 5. 系统复位
    NVIC_SystemReset();
}


//看门狗任务：可选以下新建一个任务，也可以直接采用FreeRTOS 内部的osTimer
// #include "iwdg.h"
// void MainTask(void *argument)
// {
//     /* USER CODE BEGIN MainTask */
//
//     uint32_t last_safe_point = HAL_GetTick();
//     /* Infinite loop */
//     for(;;) {
//         /* 1. 核心喂狗操作 */
//         HAL_IWDG_Refresh(&hiwdg);
//
//         /* 2. 安全点检查（比看门狗更早发现问题）*/
//         if(HAL_GetTick() - last_safe_point > 300) { // 早于400ms超时
//             emergency_handle("System delay detected");
//         }
//         last_safe_point = HAL_GetTick();
//
//         osDelay(100); // 实际周期=100ms < 133ms
//     }
//     /* USER CODE END MainTask */
// }
